package mx.itesm.gda.clever.ui;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import cml.TokenType;
import cml.scanning.Scanner;

public final class TokensView extends ViewPart {
	
	public static final String ID = "mx.itesm.gda.clever.ui.TokensView";
	
	private Table table;
	
	private IDocument document;
	
	private IDocumentListener modificationListener = new ModificationListener();
	
	private String[] columnHeaders = {
			LocalizedMessages.TokensView_typeHeader,
			LocalizedMessages.TokensView_lexemeHeader,
			LocalizedMessages.TokensView_lineHeader
	};
	
	private ColumnLayoutData[] columnLayouts = {
			new ColumnPixelData(150, true),
			new ColumnPixelData(200, true),
			new ColumnPixelData(60, true)
	};
	
	@Override
	public void createPartControl(final Composite parent) {
		
		// Create table.
		
		table = new Table(parent,
				SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION);
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		
		final TableLayout layout = new TableLayout();
		table.setLayout(layout);
		for (int i = 0; i < columnHeaders.length; i++) {
			final TableColumn column = new TableColumn(table, SWT.NONE, i);
			column.setText(columnHeaders[i]);
			layout.addColumnData(columnLayouts[i]);
		}
	}
	
	public void scan(final ITextEditor editor) throws IOException {
		if (document != null) {
			document.removeDocumentListener(modificationListener);
			document = null;
		}
		
		final IDocumentProvider provider = editor.getDocumentProvider();
		if (provider == null) return;
		
		document = provider.getDocument(editor.getEditorInput());
		document.addDocumentListener(modificationListener);
		
		scan();
	}
	
	private void scan() throws IOException {
		final String text = document.get();
		
		final Scanner scanner = new Scanner(new ByteArrayInputStream(text.getBytes()));
		TokenType token;
		
		table.removeAll();
		while ((token = scanner.getToken()) != TokenType.ENDFILE) {
			final TableItem item = new TableItem(table, SWT.NONE);
			item.setText(0, token.toString());
			item.setText(1, scanner.getTokenString());
			item.setText(2, String.valueOf(scanner.getCurrentLine() + 1));
		}
	}
	
	@Override
	public void setFocus() {
		table.setFocus();
	}
	
	private class ModificationListener implements IDocumentListener {
		
		@Override
		public void documentAboutToBeChanged(final DocumentEvent event) {}
		
		@Override
		public void documentChanged(final DocumentEvent event) {
			try {
				scan();
			} catch (final IOException ignore) {
				System.out.println(ignore);
			}
		}
		
	}
	
}
